package top.wilsonlv.jaguar.cloud.auth.security;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.DependsOn;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import top.wilsonlv.jaguar.cloud.auth.properties.FeignClientServiceMeta;
import top.wilsonlv.jaguar.cloud.auth.properties.JaguarAuthProperties;
import top.wilsonlv.jaguar.cloud.auth.sdk.spi.SecurityUserService;
import top.wilsonlv.jaguar.cloud.upms.sdk.feign.RemoteDeviceService;
import top.wilsonlv.jaguar.cloud.upms.sdk.feign.RemoteUserService;
import top.wilsonlv.jaguar.cloud.upms.sdk.vo.DeviceVO;
import top.wilsonlv.jaguar.commons.web.util.WebUtil;
import top.wilsonlv.jaguar.security.model.SecurityUser;

import javax.servlet.http.HttpServletRequest;
import java.beans.Introspector;
import java.util.Map;

/**
 * @author lvws
 * @since 2021/6/30
 */
@Slf4j
@Component
@DependsOn("feignClientServiceClassLoader")
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

    private final RemoteUserService remoteUserService;

    private final RemoteDeviceService remoteDeviceService;

    private final JaguarAuthProperties jaguarAuthProperties;

    private final ApplicationContext applicationContext;


    private SecurityUserService getSecurityUserService() {
        HttpServletRequest request = WebUtil.getRequest();
        assert request != null;
        String userType = request.getParameter("userType");

        if (!StringUtils.hasText(userType) || RemoteUserService.USER_TYPE.equals(userType)) {
            return remoteUserService;
        }

        SecurityUserService securityUserService = null;
        Map<String, SecurityUserService> serviceMap = applicationContext.getBeansOfType(SecurityUserService.class);
        for (FeignClientServiceMeta serviceMeta : jaguarAuthProperties.getSecurityUserServices()) {
            if (serviceMeta.getReserved().equals(userType)) {
                securityUserService = serviceMap.get(Introspector.decapitalize(serviceMeta.getClassName()));
                break;
            }
        }
        if (securityUserService == null) {
            throw new UsernameNotFoundException("无效的用户类型");
        }
        return securityUserService;
    }

    @Override
    public SecurityUser loadUserByUsername(String username) throws UsernameNotFoundException {
        SecurityUser securityUser = getSecurityUserService().loadUserByUsername(username).getData();
        if (securityUser == null) {
            throw new UsernameNotFoundException(null);
        }
        return securityUser;
    }

    public SecurityUser[] loadUsersByDeviceUid(String deviceUid, Long userId) throws UsernameNotFoundException {
        return getSecurityUserService().loadUsersByDeviceUid(deviceUid, userId).getData();
    }

    public DeviceVO loadDevice(String deviceUid) {
        return remoteDeviceService.loadDevice(deviceUid).getData();
    }


}
